package org.bluedream.core.config.advice;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.comm.utils.EncryForRSAUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;

@ControllerAdvice(basePackages = "org.bluedream.core.module.**.controller")
public class RsaDecodeRequestBodyAdvice implements RequestBodyAdvice {
    private static final Logger logger = LoggerFactory.getLogger(RsaDecodeRequestBodyAdvice.class);

    /**
     * RequestBody 注解时，执行当前Advice的业务
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        System.out.println("Demo Advice");
        System.out.println(methodParameter.hasParameterAnnotation(RsaSecurityParameter.class));
        return methodParameter.hasParameterAnnotation(RsaSecurityParameter.class);
    }

    /**
     * 无请求时的处理
     * @param o
     * @param httpInputMessage
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     */
    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        try {
            boolean encode = false;
            if (methodParameter.getParameter().isAnnotationPresent(RsaSecurityParameter.class)){
                System.out.println("2222 = " + methodParameter.getParameter());
                System.out.println("333 = " + httpInputMessage);
                RsaSecurityParameter serializedField = methodParameter.getParameterAnnotation(RsaSecurityParameter.class);
                encode = serializedField.inDecode();
            }
            if (encode){
                logger.info("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行解密");
                return new CustomHttpInputMessage(httpInputMessage);
            }else {
                return httpInputMessage;
            }
        }catch (Exception e1){
            e1.printStackTrace();
            logger.error("对方法method :【" + methodParameter.getMethod().getName() + "】返回数据进行解密出现异常："+e1.getMessage());
            return httpInputMessage;
        }
    }

    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }

    class CustomHttpInputMessage implements HttpInputMessage {
        private HttpHeaders headers;
        private InputStream stream;
        private String RASKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOU+Sxj8LJB5zG9/lb2BbkiduqCIolrEeoL8e4g8QSJMomKPJ3FJX1Gt8s5RTq8R741T579bxmCrF/0gyRk3WMa6lHxmH2JZiXn4ALZyfzhKMPhYeFQDQinH96pkmN1cgT51+5paRbBhgrdU6UNWg7W58Xa9Zv+xaSZzxtzmmUF5AgMBAAECgYADU3pttf/0By5gCkT7C0kVOOOjr2PSpxHje2QT85La22uKPEs9VawSQHC6zVtzxxH3lhlxUXSxA559G9gLG35YWcSLhU1vrpSI1gQSLpyrHfLyNtVGWzOGtFEwNx20x+HDrXX8NCFcpzWxhD78LjG3IMyVsJYxuPbpNzlatwL5sQJBAP0weu3O6Z8OjYmY0XyMlKm/LrLfAuTzP2HkDvnuRbr32QLx7NNaXwPIVhUFP5v+NvmFlKLVbbKVeiDemeIzihECQQDnycNAqdvVLRsyFzU93w8EJFdi5rOx8WKVOFBjljFNMIkpftBk8goaXKl8VNcFw7NQZl34AR1gwWJzzR69zxjpAkACNrNMcvut7VWld1WVjjEajtZcsAB5efr64yCSZNftO4+FLBJTAr5D7TN7eZFFzuIyKk3TYqRT5GSt9uRHiwXRAkEAltQOAEgHywJdDg1YEfjSdqmHS84/5Gzk76EDfqo/TrFkr+HbjbSKqnjduRAkE5YzWwAh6b4f9dQhUqWJeY4H8QJAJ9OuTW5WlDtmM/A/H+SzaO0R2TBK11gYI/D0jMbqEnt+guMQwaxfv5GQ7VPK7C/vFiR6OhOHoutPiYnSsyRoHQ==";

        public CustomHttpInputMessage(HttpInputMessage inputMessage) throws Exception{
            this.headers = inputMessage.getHeaders();
            String content = easpString(IOUtils.toString(inputMessage.getBody() , "utf-8"));
            this.stream = IOUtils.toInputStream(EncryForRSAUtil.decryByByRSAKey(content , RASKey , EncryForRSAUtil.PRIVATE_KEY));
        }

        @Override
        public InputStream getBody() throws IOException {
            return this.stream;
        }

        @Override
        public HttpHeaders getHeaders() {
            return this.headers;
        }

        public String easpString(String arg0){
            if (EmptyUtil.isNoEmpty(arg0)){
                String s = "{\"requestData\":";
                if (!arg0.startsWith(s)){
                    throw new RuntimeException("参数【requestData】缺失异常！");
                }else {
                    int closeLen = arg0.length()-1;
                    int openLen = s.length();
                    String substring = StringUtils.substring(arg0, openLen, closeLen);
                    return substring;
                }
            }
            return "";
        }
    }
}
